 1.数组和元组之数组定义
   
   数组几乎是所有语言中最基础的数据结构。数组可索引、类型一致、长度不变。
package lagou.cn.part03
import scala.collection.mutable.ArrayBuffer
/**
 * 在scala中，数组分为定长数组和变长数组
 * 定长数组。Array，长度是不变的
 * 变长数组，ArrayBuffer，长度是可变的,它等效与Java中的ArrayList
 * 使用变长数组之前需要导入包scala.collection.mutable.ArrayBuffer
 */
object ArrayDemo {
  def main(args: Array[String]): Unit = {
    println("===========定长数组===============")
    //定义长度为10的整型数组，初始值为0
    val nums = new Array[Int](10)
    //定义长度为10的字符串数组，初始值为null
    val strs = new Array[String](10)
    //访问数组元素，索引从0开始，使用()而不是[]来访问元素
    println(strs(0))

    //省略了关键字new，那么Scala会进行自动类型推断
    val arrays: Array[Int] = Array(1, 2, 3, 4)
    val arrays2: Array[Nothing] = Array()
    println(arrays.length)

    //通过toArray快速定义数组，用于测试
    val numsList: Array[Int] =(1 to 10).toArray
  }
}

 2.变长数组
   
   长度按需要变换的数组ArrayBuffer。Scala 中很多数组类型都有可变、不可变两个版本，推荐使用不可
变的数组类型，使用可变数组类型时需要显示声明；
   使用ArrayBuffer时，需要导包 import scala.collection.mutable.ArrayBuffer；

package lagou.cn.part03
import scala.collection.mutable.ArrayBuffer
/**
 * 在scala中，数组分为定长数组和变长数组
 * 定长数组。Array，长度是不变的
 * 变长数组，ArrayBuffer，长度是可变的,它等效与Java中的ArrayList
 * 使用变长数组之前需要导入包scala.collection.mutable.ArrayBuffer
 */
object ArrayDemo {
  def main(args: Array[String]): Unit = {
   
    println("===========变长数组===============")
    //定义一个空的Int的变长数组
    //注意：后面要有小括号
    val numsBuffer=ArrayBuffer[Int]()

    //通过+=在尾端添加一个或多个元素
    numsBuffer += 1
    numsBuffer += (2,3,4,5)
    //通过++=在尾端添加集合
    numsBuffer ++=Array(6, 7, 8)
    numsBuffer.foreach(println(_))
    //还可通过-= --=对变长数组进行删减
    numsBuffer -=8
    numsBuffer --=Array(6,7)
    println("=================删减后的变长数组==================")
    numsBuffer.foreach(println(_))

    //使用append追加一个或多个元素
    numsBuffer.append(1)
    numsBuffer.append(2,3,4)
    println("=================追加后的变长数组==================")
    numsBuffer.foreach(println(_))

    //在某个索引之前插入元素
    numsBuffer.insert(2,10)
    numsBuffer.insert(2,20,30)
    println("=================插入后的变长数组==================")
    numsBuffer.foreach(println(_))

    //移除元素
    //trimEnd 移除最后的N个元素
    numsBuffer.trimEnd(3)
    //trimStart移除去最开始的一个或多个元素
    numsBuffer.trimStart(2)
    println("=================移除后的变长数组==================")
    numsBuffer.foreach(println(_))

    //通过remove从某索引处移除一个或多个元素
    numsBuffer.remove(3)
    numsBuffer.remove(2,3)
    println("=================remove后的变长数组==================")
    numsBuffer.foreach(println(_))
  }
}


 3.数组操作
   
   数组转换
   //toArray，变长数组转换为定长数组
    val numArray: Array[Int] = numsBuffer.toArray
    //toBuffer,定长数组转换为变长数组
    var arrayBuffer: mutable.Buffer[Int] = arrays.toBuffer

    println("======================数组遍历===================================")
    println("===================使用until进行数组遍历=========================")
    for(i <- 0 until(arrays.length)){
      println(arrays(i))
    }
    println("===================使用to进行数组遍历============================")
    for (i <-0 to arrays.length-1) {
      println(arrays(i))
    }
    println("===================使用增强for循环的方式进行数组遍历=============")
    for (elem <- arrays) println(elem)
    println("===================使用foreach进行数组遍历=======================")
    arrays.foreach(println(_))

 4.常见算法
   
   在Scala中对数组进行转换非常简单方便，这些转换动作不会修改原始数组，而是产生一个全新的数组。
   任务：将数组中偶数元素加倍，奇数元素丢弃

package lagou.cn.part03

object OperatorDemo {
  def main(args: Array[String]): Unit = {
    //将数组中的偶数加倍，奇数丢弃
    val nums=(1 to 10).toArray
    val result1=for (elem <- nums if elem % 2 == 0) yield elem * 2
    val result2=for (elem <- nums) yield if(elem%2==0) elem*2
    result1.foreach(println(_))
    println("=====================================================")
    result2.foreach(println(_))

    //使用Scala中的高阶函数来实现
    println("=====================================================")
    nums.filter(_%2==0).map(_*2).foreach(println(_))

    println("=====================================================")
    //获取第一个元素
    println(nums.head)
    //获取最后一个元素
    println(nums.last)
    //获取除了第一个元素之外的其他元素
    println(nums.tail.toBuffer)
    //获取除了最后一个元素之外的其他元素
    println(nums.init.toBuffer)

    println("=====================================================")
    //求和
    println(nums.sum)
    //求最大值
    println(nums.max)
    //求最小值
    println(nums.min)

    println("=====================================================")
    val nums2=Array(2,1,4,3)
    //数组元素排序，升序
    println(nums2.sorted.toBuffer)
    //数组元素相乘
    println(nums2.product)

    println("=====================================================")

    val nums3=Array(1,2,3,4,3,2,1)
    println(nums3.map(_ * 2).toBuffer)
    println(nums3.reduce(_+_))
    //将数组中的数据进行去重
    println(nums3.distinct.toBuffer)
    println(nums3.length)
    println(nums3.size)
    //获取数组中每个元素的索引
    println(nums3.indices.toBuffer)

    println("=====================================================")
    //使用mkString进行输出
    println(nums3.mkString(" & "))
    println(nums3.mkString("<"," & ",">"))

    //count计数，注意：count后面必须有条件
    println(nums3.count(_>2))
    println(nums3.count(_%2 == 0))

    //filter过滤出符合条件的数据 filterNot过滤出不符合条件的数据
    println(nums3.filter(_>2).toBuffer)
    println(nums3.filterNot(_ % 2 == 0).toBuffer)

    println("=====================================================")
    //take提取前N个元素
    println(nums3.take(3).toBuffer)
    //takeRight提取最后N个元素
    println(nums3.takeRight(4).toBuffer)
    //takeWhile从左向右进行提取，提取出符合条件的元素，如果条件不成立就终止提取
    println(nums3.takeWhile(_<4).toBuffer)

    println("=====================================================")
    //删除前N个元素
    println(nums3.drop(3).toBuffer)
    //删除后N个元素
    println(nums3.dropRight(3).toBuffer)
    //从左向右删除符合条件的元素，如果条件不成立，就终止删除操作
    println(nums3.dropWhile(_ <4).toBuffer)

    println("=====================================================")
    //将数组分为两部分，前N个为一部分，剩下为另一部分
    var tuple: (Array[Int], Array[Int]) = nums3.splitAt(3)
    println(tuple._1.toBuffer+ " "+tuple._2.toBuffer)
    //对数组进行切片操作，取出从索引2到索引4的元素，不包括索引为5的元素
    println(nums3.slice(2,5).toBuffer)

    println("=====================================================")
    val array1=Array("A","B","C")
    val array2=Array(1,2,3,4)
    //拉链操作，当两个数组的长度不一样时，截取相同的长度
    val z1: Array[(String, Int)] = array1.zip(array2)
    println(z1.toBuffer)

    //拉链操作，当两个长度不一样时，array1用*填充，array2用-1填充
    val z2 = array1.zipAll(array2, "*", -1)
    //拉链操作，当两个长度不一样时，array2用*填充，array1用-1填充
    val z3 = array2.zipAll(array1, "*", -1)
    //用数组索引进行填充
    val z4 = array1.zipWithIndex
    println(z2.toBuffer)
    println(z3.toBuffer)
    println(z4.toBuffer)

    println("=====================================================")
    //通过unzip进行拆分数组的操作
    //通过unzip把z4拆分成两个数组
    val (l1,l2)=z4.unzip
    println(l1.toBuffer)
    println(l2.toBuffer)

    val (l3,l4,l5)=Array((1,"one",'1'),(2,"two",'2'),(3,"three",'3')).unzip3
    println(l3.toBuffer)
    println(l4.toBuffer)
    println(l5.toBuffer)

    //数组的操作符：:+ +: ++
    // :+用于数组的尾部追加元素；+：用于在数组的头部追加元素
    // ++用于连接两个集合(比如：数组、列表等)
    val num1=(1 to 4).toArray
    val num2=(5 to 8).toArray

    val num3 = 10 +: num1
    val num4 = num2 :+ 9
    val num5 = num1 ++ num2

    println("=====================================================")
    println(num3.toBuffer)
    println(num4.toBuffer)
    println(num5.toBuffer)

    println("======================数组排序=========================")
    val sortNums=Array(1,3,5,2,7,8,6,9)
    //升序
    println(sortNums.sorted.toBuffer)
    //降序
    println(sortNums.sorted.reverse.toBuffer)
    //降序
    println(sortNums.sortWith(_>_).toBuffer)
    //升序
    println(sortNums.sortWith(_<_).toBuffer)

  }

}


 5.多维数组
   
   通过Array的ofDim方法来定义一个多维的数组，多少行，多少列，都是自己说了算。
package lagou.cn.part03

object MultipleArrayDemo {
  def main(args: Array[String]): Unit = {
    //定义一个3行4列的二维数组
    val dim=Array.ofDim[Double](3,4)
    dim(1)(1) = 12.5
    for (i <- 0 to 2; j <-0 to 3) {
      print(dim(i)(j)+"   ")
      if(j==3) println()
    }
  }
}

 6.元组及操作
   
   Tuple，元组。Map是键值对的集合。对偶是元组的最简单形态；
   元组是不同类型的值的集合，元组中的元素可以是不同的数据类型，元组在Scala中的应用非常广泛。

package lagou.cn.part03

/**
 * Tuple元组，可以存放不同数据类型的元素
 * 元组的索引从1开始，不是从0开始
 * 元组在Scala中应用非常广泛，在Spark的源码中会见到很多元组
 * 在Scala中，已经事先定义了22个Tuple，从Tuple1~~Tuple22
 * 在Tiple22中，最多只能有22个元素
 */
object TupleDemo {
  def main(args: Array[String]): Unit = {
    //定义一个元组
    val tuple=(1, 2.5, "spark", 'a',true)
    val tuple2=(1, 1.2, "scala", 'b')
    println(tuple == tuple2)

    println(tuple._3)

    //从元组中接收数据
    val (t1, t2, t3, t4), t5 =tuple2
    println(s"$t1 $t2 $t3 $t4")

    val (b1,_,b2,_), b5=tuple2
    println(s"$b1  $b2")

    //遍历元组
    for (t <- tuple.productIterator) {
      println(t)
    }
    println("=====================================")
    tuple.productIterator.foreach(println(_))
  }

}
